package com.hyzh.latte.vehicle.repository;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hyzh.latte.vehicle.config.MinioConfig;
import com.hyzh.latte.vehicle.dmo.VehicleTrackCameraVO;
import com.hyzh.latte.vehicle.dmo.VehicleVO;
import com.hyzh.latte.vehicle.dmo.entity.VehicleTrackRecordPGEntity;
import com.hyzh.latte.vehicle.repository.mapper.VehicleTrackRecordPGMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@AllArgsConstructor
public class VehicleTrackRecordPGRepository extends ServiceImpl<VehicleTrackRecordPGMapper, VehicleTrackRecordPGEntity> {

    private final MinioConfig minioConfig;

    public List<String> listVehicleNo(String vno, LocalDateTime startTime, LocalDateTime endTime) {
        List<VehicleTrackRecordPGEntity> list = this.lambdaQuery()
                .select(VehicleTrackRecordPGEntity::getVehicleNo, VehicleTrackRecordPGEntity::getCount)
                .likeRight(StrUtil.isNotEmpty(vno), VehicleTrackRecordPGEntity::getVehicleNo, vno)
                .gt(null != startTime, VehicleTrackRecordPGEntity::getAddTime, startTime)
                .lt(null != endTime, VehicleTrackRecordPGEntity::getAddTime, endTime)
                .groupBy(VehicleTrackRecordPGEntity::getVehicleNo).list();

        if (CollectionUtil.isEmpty(list)) {
            log.info("vehicleNo: vno data is null, park: {}", "guangyuan");
            return null;
        }
        list = list.stream().sorted(Comparator.comparing(VehicleTrackRecordPGEntity::getCount).reversed()).collect(Collectors.toList());
        return list.stream().map(VehicleTrackRecordPGEntity::getVehicleNo).collect(Collectors.toList());
    }


    public List<VehicleVO>  listVehicleVO(String vno, LocalDateTime startTime, LocalDateTime end) {
        List<VehicleTrackRecordPGEntity> list = listGateTrack(vno, startTime, end);
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        List<VehicleVO> resultList = new ArrayList<>();
        Map<String, List<VehicleTrackRecordPGEntity>> map = list.stream().collect(Collectors.groupingBy(VehicleTrackRecordPGEntity::getVehicleNo));
        for (Map.Entry<String, List<VehicleTrackRecordPGEntity>> entry : map.entrySet()) {
            VehicleVO vehicleVO = verifyData(entry.getValue());
            if (null != vehicleVO) {
                resultList.add(vehicleVO);
            }
        }

        return resultList;
    }
    public List<VehicleVO>  listVehicleVOOnline(String vno, LocalDateTime startTime, LocalDateTime end) {
        List<VehicleTrackRecordPGEntity> list = listGateTrack(vno, startTime, end);
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        List<VehicleVO> resultList = new ArrayList<>();
        Map<String, List<VehicleTrackRecordPGEntity>> map = list.stream().collect(Collectors.groupingBy(VehicleTrackRecordPGEntity::getVehicleNo));
        for (Map.Entry<String, List<VehicleTrackRecordPGEntity>> entry : map.entrySet()) {
            VehicleVO vehicleVO = verifyDataOnline(entry.getValue());
            if (null != vehicleVO) {
                resultList.add(vehicleVO);
            }
        }

        return resultList;
    }

    private VehicleVO verifyDataOnline(List<VehicleTrackRecordPGEntity> data){
        if (data.size() < 2){
            return null;
        }
        VehicleTrackRecordPGEntity entity = data.get(data.size()-1);
        return new VehicleVO(entity.getVehicleNo(), "1", entity.getAddTime());
    }
    private VehicleVO verifyData(List<VehicleTrackRecordPGEntity> data){
        if (data.size() < 4){
            return null;
        }
        List<VehicleTrackRecordPGEntity> list = data.stream().filter(d -> d.getDoType() == 9 || d.getDoType() == 8).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(list) || list.size() < 3){
            return null;
        }

        list = list.stream().sorted(Comparator.comparing(VehicleTrackRecordPGEntity::getAddTime)).collect(Collectors.toList());
        Iterator<VehicleTrackRecordPGEntity> iterator = list.iterator();
        while (iterator.hasNext()){
            VehicleTrackRecordPGEntity vte = iterator.next();
            if (vte.getDit() == -9 || vte.getDit() == 8){
                iterator.remove();
            }else if (vte.getDit() == 9 || vte.getDit() == -8){
                break;
            }
        }

        if (CollectionUtil.isEmpty(list) || list.size() < 3){
            return null;
        }

        Set<Integer> dictSet = list.stream().map(VehicleTrackRecordPGEntity::getDit).collect(Collectors.toSet());
        if (CollectionUtil.isEmpty(dictSet) || dictSet.size() < 2) {
            return null;
        }

        if (dictSet.stream().noneMatch(i -> i == 9 || i == -8)){
            return null;
        }
        if (dictSet.stream().noneMatch(i -> i == -9 || i == 8)){
            return null;
        }
        VehicleTrackRecordPGEntity entity = data.get(data.size()-1);
        return new VehicleVO(entity.getVehicleNo(), "1", entity.getAddTime());
    }


    //查询所有数据
    private List<VehicleTrackRecordPGEntity> listGateTrack(String vno, LocalDateTime startTime, LocalDateTime endTime){
        List<VehicleTrackRecordPGEntity> list =  this.lambdaQuery()
                .select(VehicleTrackRecordPGEntity::getVehicleNo, VehicleTrackRecordPGEntity::getVehicleType, VehicleTrackRecordPGEntity::getDoType, VehicleTrackRecordPGEntity::getDit,  VehicleTrackRecordPGEntity::getAddTime )
                .likeRight(StrUtil.isNotEmpty(vno), VehicleTrackRecordPGEntity::getVehicleNo, vno)
                .isNotNull(VehicleTrackRecordPGEntity::getPoleCode)
                .gt(null != startTime, VehicleTrackRecordPGEntity::getAddTime, startTime)
                .lt(null != endTime,  VehicleTrackRecordPGEntity::getAddTime, endTime)
                .orderByAsc(VehicleTrackRecordPGEntity::getAddTime)
//                .last("LIMIT 400000")
                .list();

        if (CollectionUtil.isEmpty(list)){
            log.info("vehicleNo: vno data is null, park: {}", "jiangan");
            return null;
        }
        return list;
    }

    public List<VehicleTrackRecordPGEntity> listTrackRecord(String vo, LocalDateTime startTime, LocalDateTime endTime) {
        List<VehicleTrackRecordPGEntity> list =  this.lambdaQuery()
                .eq(VehicleTrackRecordPGEntity::getVehicleNo, vo)
                .isNotNull(VehicleTrackRecordPGEntity::getPoleCode)
                .gt(null != startTime, VehicleTrackRecordPGEntity::getAddTime, startTime)
                .lt(null != endTime,  VehicleTrackRecordPGEntity::getAddTime, endTime)
                .orderByAsc(VehicleTrackRecordPGEntity::getAddTime).list();

        if (CollectionUtil.isEmpty(list)){
            log.info("vehicleTrack: history data is null, vno: {}", vo);
            return null;
        }

        return list;
    }

    public List<VehicleTrackRecordPGEntity> listVehicleTrack(LocalDateTime startTime, LocalDateTime endTime) {
        List<VehicleTrackRecordPGEntity> list =  this.lambdaQuery()
                .gt(null != startTime, VehicleTrackRecordPGEntity::getAddTime, startTime)
                .lt(null != endTime,  VehicleTrackRecordPGEntity::getAddTime, endTime)
                .orderByAsc(VehicleTrackRecordPGEntity::getAddTime).list();

        if (CollectionUtil.isEmpty(list)){
            log.info("listVehicleTrack: history data is null, ");
            return null;
        }

        return list;
    }



    public List<VehicleTrackCameraVO> enterpriseCamera(String cno, String vno, LocalDateTime startTime, LocalDateTime endTime) {
        List<VehicleTrackRecordPGEntity> list =  this.lambdaQuery()
                .select(VehicleTrackRecordPGEntity::getVehicleNo,
                        VehicleTrackRecordPGEntity::getVehicleType,
                        VehicleTrackRecordPGEntity::getCameraCode,
                        VehicleTrackRecordPGEntity::getMinioObj,
                        VehicleTrackRecordPGEntity::getEnterprises,
                        VehicleTrackRecordPGEntity::getAddTime )
                .likeRight(StrUtil.isNotEmpty(cno), VehicleTrackRecordPGEntity::getCameraCode, cno)
                .likeRight(StrUtil.isNotEmpty(vno), VehicleTrackRecordPGEntity::getVehicleNo, cno)
                .in(VehicleTrackRecordPGEntity::getDoType, 1, -1)
                .gt(null != startTime, VehicleTrackRecordPGEntity::getAddTime, startTime)
                .lt(null != endTime,  VehicleTrackRecordPGEntity::getAddTime, endTime)
                .orderByDesc(VehicleTrackRecordPGEntity::getAddTime)
                .last("LIMIT 100")
                .list();

        if (CollectionUtil.isEmpty(list)){
            log.info("vehicleNo: vno data is null, park: {}", "jiangan");
            return null;
        }

        return list.stream().map(x -> {
            VehicleTrackCameraVO vo = new VehicleTrackCameraVO();
            vo.setVehicleNo(x.getVehicleNo());
            vo.setCameraCode(x.getCameraCode());
            vo.setVehicleType(x.getVehicleType());
            vo.setAddTime(x.getAddTime());
            vo.setDoType(x.getDoType());
            vo.setImagePath(Optional.ofNullable(x.getMinioObj()).map(o -> minioConfig.getPath()+o).orElse(null));
            vo.setEnterpriseName(x.getEnterprises());
            return vo;
        }).collect(Collectors.toList());
    }



}
